package com.ran.java_gobang_new.service;

import java.util.concurrent.*;
import com.ran.java_gobang_new.manager.OnlineManager;
import com.ran.java_gobang_new.manager.RoomManager;
import com.ran.java_gobang_new.my_exception.MatchException;
import com.ran.java_gobang_new.pojo.dao.Room;
import com.ran.java_gobang_new.pojo.response.Result;
import com.ran.java_gobang_new.pojo.response.UserInfoGameHallReponse;
import com.ran.java_gobang_new.utils.JsonTrans;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;


/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ran
 * Date: 2025-09-03
 * Time: 22:24
 */
@Service
@Slf4j
public class MatchService {
    // 处理匹配队列的请求
    // 设立三个队列, 初阶, 中阶, 高阶
    private static BlockingDeque<UserInfoGameHallReponse> newerQueue = new LinkedBlockingDeque(1000);
    private static BlockingDeque<UserInfoGameHallReponse> higherQueue = new LinkedBlockingDeque(1000);
    private static BlockingDeque<UserInfoGameHallReponse> veryHigherQueue = new LinkedBlockingDeque(1000);

    // 添加进匹配队列
    public void add(UserInfoGameHallReponse userInfoGameHallReponse) {
        try {
            if (userInfoGameHallReponse.getScore() < 2000) {
                synchronized (newerQueue) {
                    log.info("玩家: " + userInfoGameHallReponse.getUserName() + " 加入初阶队列!");
                    newerQueue.put(userInfoGameHallReponse);
                    newerQueue.notify();
                }
            }else if (userInfoGameHallReponse.getScore() >= 2000 && userInfoGameHallReponse.getScore() < 3000) {
                synchronized (higherQueue) {
                    log.info("玩家: " + userInfoGameHallReponse.getUserName() + " 加入中阶队列!");
                    higherQueue.put(userInfoGameHallReponse);
                    higherQueue.notify();
                }
            }else {
                synchronized (veryHigherQueue) {
                    log.info("玩家: " + userInfoGameHallReponse.getUserName() + " 加入高阶队列!");
                    veryHigherQueue.put(userInfoGameHallReponse);
                    veryHigherQueue.notify();
                }
            }
        }catch (NullPointerException e) {
            // 说明当前 用户 没有登录
            throw new MatchException("您当前未登录");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

    // 从匹配队列中删除
    public void remove(UserInfoGameHallReponse userInfoGameHallReponse) {
        try {
            if (userInfoGameHallReponse.getScore() < 2000) {
                synchronized (newerQueue) {
                    log.info("玩家: " + userInfoGameHallReponse.getUserName() + " 从初阶队列删除!");
                    newerQueue.remove(userInfoGameHallReponse);
                }
            }else if (userInfoGameHallReponse.getScore() >= 2000 && userInfoGameHallReponse.getScore() < 3000) {
                synchronized (higherQueue) {
                    log.info("玩家: " + userInfoGameHallReponse.getUserName() + " 从初阶队列删除!");
                    higherQueue.remove(userInfoGameHallReponse);
                }
            }else {
                synchronized (veryHigherQueue) {
                    log.info("玩家: " + userInfoGameHallReponse.getUserName() + " 从初阶队列删除!");
                    veryHigherQueue.remove(userInfoGameHallReponse);
                }
            }
        }catch (NullPointerException e) {
            // 说明当前 用户 没有登录
            throw new MatchException("您当前未登录");
        }
    }


    public MatchService() {

        Thread t1 = new Thread() {
            @Override
            public void run() {
                // 扫描 normalQueue
                while (true) {
                    handlerMatch(newerQueue);
                }
            }
        };
        t1.start();

        Thread t2 = new Thread(){
            @Override
            public void run() {
                while (true) {
                    handlerMatch(higherQueue);
                }
            }
        };
        t2.start();

        Thread t3 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    handlerMatch(veryHigherQueue);
                }
            }
        };
        t3.start();
    }

    @Autowired
    private RoomManager roomManager;
    @Autowired
    private OnlineManager onlineManager;
    // 处理匹配逻辑
    public void handlerMatch(BlockingDeque<UserInfoGameHallReponse> deque) {
        // 查看当前匹配队列有多少人
        // 谁调用就用谁加锁
        synchronized (deque) {
            try {
                // 当前队列不够两个人
                while (deque.size() < 2) {
                    deque.wait();
                }
                // 从队列取出两个玩家
                UserInfoGameHallReponse player1 = deque.take();
                UserInfoGameHallReponse player2 = deque.take();

                // 再次判断玩家是否在线, 防止成功时突然关闭了网页
                WebSocketSession session1 = onlineManager.getHallSession(player1.getUserId());
                WebSocketSession session2 = onlineManager.getHallSession(player2.getUserId());
                if (session1 == null) {
                    log.error("玩家1匹配时 " + player1.getUserName() + " 掉线");
                    // 再次把玩家2加入匹配队列
                    deque.offer(player2);
                    return;
                }
                if (session2 == null) {
                    log.error("玩家2匹配时 " + player2.getUserName() + " 掉线");
                    // 再次把玩家1加入匹配队列
                    deque.offer(player1);
                    return;
                }
                // 双开
                if (session1 == session2) {
                    log.error("用户: " +player1.getUserName()+ " 双开");
                    deque.offer(player1);
                    return;
                }
                // 添加进房间
                Room room = new Room();
                roomManager.add(room,player1.getUserId(),player2.getUserId());
                log.info("玩家1:" + player1.getUserName() + " 进入游戏房间!");
                log.info("玩家2:" + player2.getUserName() + " 进入游戏房间!");
                // 通知双方, 都准备好了, 都匹配成功, 发送给双方
                session1.sendMessage(JsonTrans.trans(Result.success("success")));
                session2.sendMessage(JsonTrans.trans(Result.success("success")));


            } catch (InterruptedException | IOException e) {
                log.error("匹配服务发生异常, e: ",e);
                throw new RuntimeException(e);
            }
        }
    }

}
